package com.burial.common.aspect;

import com.burial.common.log.MyLog;
import com.burial.common.mapper.MylogMapper;
import domian.Message;
import domian.Mylog;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: 靳训硕
 * @Date: 2024/04/23/10:38
 **/

//声明这是一个组件

//声明这是一个切面Bean
@Aspect
public class TestAspect {
    //全局实体信息
    Message message = new Message();

    @Autowired
    private MylogMapper mapper;

    /**
     * 设置操作日志切入点 记录操作日志 在注解的位置切入代码
     */
    @Pointcut("@annotation(com.burial.common.log.MyLog)")
    public void aspect(){   }

    //最终通知
    //returning能够将目标方法的返回值传到切面增强方法里
    //声明rvt时指定的类型会限制目标方法必须返回指定类型(String)的值或没有返回值
    //此处将rvt的类型声明为Object，意味着对目标方法的返回值不加限制
    @AfterReturning(pointcut ="aspect()",returning = "rvt")
    public void AfterReturning(String rvt){
    }

    //异常通知
    //声明e时指定的类型会限制目标方法必须抛出指定类型的异常
    //此处将e的类型声明为Throwable，意味着对目标方法抛出的异常不加限制
    @AfterThrowing(pointcut="aspect()",throwing="e")
    public void AfterThrowing(Throwable e){

        System.out.println("--------AfterThrowing方法开始执行:"+e);
    }

    public Map<String, String> converMap(Map<String, String[]> paramMap) {
        Map<String, String> rtnMap = new HashMap<String, String>();
        for (String key : paramMap.keySet()) {
            rtnMap.put(key, paramMap.get(key)[0]);
        }
        Mylog mylog = new Mylog();
        mylog.setType(message.getType());
        mylog.setMsg(message.getMsg());
        mylog.setArgs(message.getArgs().toString());
        mylog.setTime(new Date());
        mapper.insert(mylog);
        return rtnMap;
    }


    //@Around注解可以用来在调用一个具体方法前和调用后来完成一些具体的任务。
    //功能很强大，可以深入了解下
    @Around("aspect()")
    public Object Around(ProceedingJoinPoint joinPoint) throws Throwable {
//        System.out.println("--------Around方法开始执行");

        Mylog mylog = new Mylog();

        //获取自定义注解里面的值
        Method method = ((MethodSignature)joinPoint.getSignature()).getMethod();
        MyLog myLog = method.getAnnotation(MyLog.class);
        String type = myLog.type();
        String msg = myLog.msg();





        Object[] objs = joinPoint.getArgs();
        String[] argNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames(); // 参数名
        Map<String, Object> args = new HashMap<String, Object>();
        for (int i = 0; i < objs.length; i++) {
            args.put(argNames[i], objs[i]);
        }
        //封装信息
        message.setMsg(msg);
        message.setType(type);
        message.setArgs(args);

        System.err.println("入参:"+ args);

        /*执行日志入库的操作*/
        mylog.setType(type);
        mylog.setMsg(msg);
        mylog.setArgs(args.toString());
        mylog.setTime(new Date());
        mapper.insert(mylog);

        Object result =joinPoint.proceed();
        return result;

    }

}

